#include <cstdint>
#include <cassert>
#include <random>
#include <algorithm>
#include <iostream>
#include "rotor.hpp"
#include "reflector.hpp"
#include "random_vector.hpp"

#define N 16


int main()
{
    using namespace clay;

    Reflector<N> reflector;
    Rotor<N> rotor(1, 123), rotor_copy;
    rotor_copy = rotor;

    std::vector<std::uint8_t> origin, origin_copy;
    origin_copy = origin = generateRandomVector<std::uint8_t, N>(0, N - 1);

    std::for_each(origin.begin(), origin.end(),
        [&reflector, &rotor](std::uint8_t& value) {
            rotor.Roll();
            value = rotor.Map(value);
            value = reflector.Map(value);
            value = rotor.ReverseMap(value);
        }
    );

    assert(!std::equal(origin.begin(), origin.end(), origin_copy.begin()));

    std::for_each(origin.begin(), origin.end(),
        [&reflector, &rotor_copy](std::uint8_t& value) {
            rotor_copy.Roll();
            value = rotor_copy.Map(value);
            value = reflector.Map(value);
            value = rotor_copy.ReverseMap(value);
        }
    );

    assert(std::equal(origin.begin(), origin.end(), origin_copy.begin()));

    return 0;
}